(setq ring-bell-function (lambda () (message "*woop*")))

(print "Loading...")

(set-language-environment "UTF-8")
(setq locale-coding-system 'utf-8)
(set-terminal-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-selection-coding-system 'utf-8)
(prefer-coding-system 'utf-8)
(global-set-key (kbd "<f5>") 'eval-buffer)

;; Load package melpa
(defun load-package-archives()
  (let ()
  (require 'package)
  (setq package-archives '(("gnu"    . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
                           ("nongnu" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/nongnu/")
                           ("melpa"  . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/")))
  (message "Package Archives: %s" package-archives)
  ;; (add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
  ;; (add-to-list 'package-archives '("melpa" . "http://melpa.milkbox.net/packages/") t)
  ;; (add-to-list 'package-archives '("marmalade" . "https://marmalade-repo.org/packages/") t)
  ;; (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/") t)
  (package-initialize)
  (package-refresh-contents)
  ))

(defun install-packages (pkgs)
  (load-package-archives)
  (dolist (p pkgs)
    (message "Checking package: %s" p)
    (unless (package-installed-p p)
      (message "Installing package: %s" p)
      (condition-case err
          (package-install p)
        (error
         (message "Error installing package %s: %s" p err)))
      (unless (package-installed-p p)
        (message "Failed to install package: %s" p))
      (message "Package %s installed." p))))


;; (defun install-packages (pkgs)
;;   (dolist (p pkgs)
;;   (message "Checking package: %s" p)
;;   (unless (package-installed-p p)
;;     (message "Installing package: %s" p)
;;     (package-install p)
;;     (message "Package %s installed." p)
;;     )
;;   ))

(defun require-all (coll)
  "require everything"
  (dolist (item coll)
    ;;    (unless (package-installed-p item)      
    ;;      (package-install item))
    (message "require: %s" item)
    (ignore-errors
      (require item))
    ))

(global-display-line-numbers-mode)

(install-packages '(
		    ggtags
		    helm
		    paredit
                    ;;paredit-menu
                    which-key
                    ibuffer
                    ido
                    ido-vertical-mode
                    auto-complete
                    yasnippet
                    multiple-cursors
                    icicles
                    ido
                    ido-vertical-mode
                    web-mode
                    ac-js2
                    ;;ac-python
                    ac-etags
                    ac-html-angular
                    ac-html-csswatcher
                    angular-mode
                    angular-snippets
                    
                    ;;ahei-misc
                    js2-refactor
                    
                    ;; auto-complete+
                    
                    ;; aes                      
                    ;; better-defaults

                    projectile
                    ;; ac-nrepl
                    ac-helm

                    noctilux-theme
                    ;; clojure-mode
                    ;; cider
                    ;; helm-clojuredocs
                    ;; ac-cider
		    magit
                    ))

(defun set-exec-path-from-shell-PATH ()
  (let ((path-from-shell
         (concat (replace-regexp-in-string "%PATH%" ""  (shell-command-to-string "echo %PATH%"))
                 (replace-regexp-in-string "$PATH" "" (shell-command-to-string "echo $PATH")))
         ))
    (message "Path: %s" path-from-shell)
    (setenv "PATH" path-from-shell)
    (setq exec-path (split-string path-from-shell path-separator))))


(defun set-auto-complete-as-completion-at-point-function ()
  (setq completion-at-point-functions '(auto-complete)))

(when (>= emacs-major-version 24)
  (require-all '(eval-after-load
                    ahei-misc
                  yasnippet
                  multiple-cursors
                  ;;icicles
                  ido
                  ido-vertical-mode
                  auto-complete-settings

                  ;; Not required
                  ;; ac-emmet
                  ;; helm-config
                  ;; cljdoc
                  ;; aes
                  ;; go-mode-autoloads
                  ;; linum
                  ))
  (when window-system (set-exec-path-from-shell-PATH))
  (fset 'yes-or-no-p 'y-or-n-p)
  (custom-set-variables
   '(column-number-mode t)
   ;; '(display-battery-mode t)
   '(inhibit-default-init t)
   '(inhibit-startup-buffer-menu t)
   '(inhibit-startup-screen t)
   ;; '(initial-buffer-choice t)
   '(initial-scratch-message "")
   ;; '(size-indication-mode t)
   '(tool-bar-mode nil)
   '(tooltip-mode nil))

  ;; Auto complete
  (require 'auto-complete-config)
  (add-to-list 'ac-dictionary-directories "~/.emacs.d/ac-dict")
  (setq ac-delay 0.0)
  (setq ac-use-quick-help t)
  (setq ac-quick-help-delay 0.0)
  (setq ac-use-fuzzy 1)
  (setq ac-auto-start 1)
  (setq ac-auto-show-menu 1)
  (ac-config-default)

  
  (add-to-list 'load-path "~/.emacs.d/elpa/auto-complete-20150618.1949/")
  (global-auto-complete-mode t)
  (ac-config-default)

  ;; paredit
  (add-hook 'nrepl-mode-hook 'paredit-mode)
  (global-set-key [f7] 'paredit-mode)

  ;; theme
  (load-theme 'noctilux t)
  (add-hook 'auto-complete-mode-hook 'set-auto-complete-as-completion-at-point-function)
  (add-hook 'cider-repl-mode-hook 'set-auto-complete-as-completion-at-point-function)
  (add-hook 'cider-mode-hook 'set-auto-complete-as-completion-at-point-function)
  ;; scroll one line at a time (less "jumpy" than defaults)

  ;; (setq mouse-wheel-scroll-amount '(1 ((shift) . 1))) ;; one line at a time
  ;; (setq mouse-wheel-progressive-speed nil) ;; don't accelerate scrolling
  ;; (setq mouse-wheel-follow-mouse 't) ;; scroll window under mouse
  ;; (setq scroll-step 1) ;; keyboard scroll one line at a time
  ;; ;; rainbow delimiters
  ;; (global-rainbow-delimiters-mode)

  ;; nrepl
  (add-hook 'nrepl-interaction-mode-hook 'nrepl-turn-on-eldoc-mode)
  (setq nrepl-popup-stacktraces nil)
  (add-to-list 'same-window-buffer-names "*nrepl*")
  (add-hook 'nrepl-mode-hook 'paredit-mode)

  ;; ac-nrepl
  ;;(require 'ac-nrepl)
  (add-hook 'nrepl-mode-hook 'ac-nrepl-setup)
  (add-hook 'nrepl-interaction-mode-hook 'ac-nrepl-setup)
  (eval-after-load "auto-complete" '(add-to-list 'ac-modes 'nrepl-mode))

  (global-set-key (kbd "C-=") 'er/expand-region)
  (global-set-key (kbd "C-S-c C-S-c") 'mc/edit-lines)
  (global-set-key (kbd "C->") 'mc/mark-next-like-this)
  (global-set-key (kbd "C-<") 'mc/mark-previous-like-this)
  (global-set-key (kbd "C-c C-<") 'mc/mark-all-like-this)
  )

(global-set-key (kbd "C-x C-b") 'ibuffer)
(global-set-key (kbd "s-w") 'aya-create)
(global-set-key (kbd "s-y") 'aya-expand)
;; (global-set-key (kbd "C-x g") 'google-search-web)
;; (global-set-key "\C-ct" 'google-translate-smooth-translate)

;; (let ((evernote-enabled nil))
;;   (when evernote-enabled
;;     (setq evernote-username "rainbowlzy@gmail.com")
;;     (setq evernote-developer-token "")
;;     (setq browse-url-browser-function 'w3m-browse-url)
;;     (setq w3m-use-cookies t)
;;     (setq w3m-coding-system 'utf-8
;; 	  w3m-file-coding-system 'utf-8
;; 	  w3m-file-name-coding-system 'utf-8
;; 	  w3m-input-coding-system 'utf-8
;; 	  w3m-output-coding-system 'utf-8
;; 	  w3m-terminal-coding-system 'utf-8)
;;     (setq enh-enclient-command "~/evernote-mode/ruby/bin/enclient.rb")

;;     (require 'evernote-mode)
;;     (setq evernote-enml-formatter-command '("w3m" "-dump" "-I" "UTF8" "-O" "UTF8"))))

;; (require 'package)
;; (add-to-list 'package-archives
;;              '("marmalade" . "https://marmalade-repo.org/packages/") t)
;; (package-initialize)

;; For clojure installation
;; (require 'package) (add-to-list 'package-archives '("melpa-stable" . "http://stable.melpa.org/packages/") t) (package-initialize)


;; fix the PATH variable

(defun set-auto-complete-as-completion-at-point-function ()
  (setq completion-at-point-functions '(auto-complete)))

(setq emmet-move-cursor-between-quotes t) ;; default nil
(setq emmet-move-cursor-after-expanding nil) ;; default t

;; (global-set-key (kbd "s-b") 'compile)
;; (global-set-key (kbd "s-r") 
;; 		(lambda () "run" (interactive)
;; 		  (if (file-exists-p "Makefile")
;; 		      (compile "make -k")
;; 		    (let ((file-to-run (replace-regexp-in-string "\\..*" "" (buffer-name))))
;; 		      (print file-to-run)
;; 		      (if (file-exists-p file-to-run)
;; 			  (let ((cmd-to-run (concat "./" (replace-regexp-in-string (buffer-name) "" (buffer-file-name)) file-to-run)))
;; 			    (print cmd-to-run)
;; 			    (async-shell-command cmd-to-run "*Application Running*" "*Running Error*")))))))

(defvar *snippets-folder* "~/emacs/snippets" "Snippet folder for yasnippet")

;; (dolist (folder '("~/emacs/emacs-lisp/")) 
;;   (add-to-list 'load-path folder)
;;   (dolist (subfolder (directory-files folder))
;;     (let ((sub-folder (concat folder subfolder)))
;;       (message sub-folder)
;;       (add-to-list 'load-path sub-folder)))) 

;; slime
;; Set your lisp system and, optionally, some contribs
;; (setq inferior-lisp-program "/opt/local/bin/clisp")
;; (setq slime-contribs '(slime-fancy))
(yas-global-mode t)
(yas/minor-mode-on)
(yas/initialize)

(setq yas-snippet-dirs '(*snippets-folder*))
(add-to-list 'yas/root-directory *snippets-folder*)

(add-hook 'progn-hook
	  (defun progn-hook-func ()
	    ""
	    (interactive)
	    ;; (setq linum-format 'linum-format-func)
	    ;; (put 'upcase-region 'disabled nil)

	    ;; (autoload 'ibuffer "ibuffer" "List buffers." t)
	    
	    (ido-mode t)
	    (ido-vertical-mode 1)
	    ;; (ido-ubiquitous-mode t)
	    ;; (ido-everywhere 1)			
	    ;; (ido-sort-mtime-mode 1)

            (yas-global-mode t)
            ;; (global-ede-mode t)
	    ;; (display-battery-mode t)
            ;;	    (global-linum-mode 1)
	    ;; (setq org-completion-use-ido t)
	    ;; (setq magit-completing-read-function 'magit-ido-completing-read)
	    ;; (setq ido-vertical-define-keys 'C-n-C-p-up-and-down)
	    (auto-complete-settings)
	    
	    ;; Show parenthesis mode
	    (show-paren-mode 1)

	    ;; (set-default-font "Microsoft YaHei")
	    ;; (set-default-font "-outline-微软雅黑-normal-normal-normal-sans-*-*-*-*-p-*-gb2312.1980-0")
	    (set-default-font "Consolas 16")
	    (toggle-truncate-lines)
	    (global-auto-complete-mode t)
            (setq ac-sources (append '(ac-source-yasnippet) ac-sources))
	    (setq ac-source-yasnippet nil)
	    (which-key-mode t)
	    ;; (which-key-setup-side-window-right)
	    ))

(add-hook 'emacs-lisp-mode-hook
	  (defun emacs-lisp-mode-hook-func ()
	    (interactive)
	    (progn-hook-func)
	    (paredit-mode t)
	    (global-set-key (kbd "s-.") 'eval-buffer)))

;; (add-hook 'csharp-mode-hook 'my-csharp-mode-hook)
;; (add-hook 'c++-mode-hook 'helm-gtags-mode)
;; (add-hook 'dired-mode-hook 'helm-gtags-mode)
;; (add-hook 'eshell-mode-hook 'helm-gtags-mode)
;; (add-hook 'c-mode-hook 'helm-gtags-mode)
;; (add-hook 'asm-mode-hook 'helm-gtags-mode)
;; (add-hook 'c-mode-common-hook 'google-set-c-style)
;; (add-hook 'c-mode-common-hook 'google-make-newline-indent)







(add-hook 'cider-mode-hook (defun cider-mode-hook-func ()
			     (interactive)
			     (eldoc-mode t)
                             (global-set-key [f6] 'cider-load-buffer)
			     ;; clojure installation end.

     			     ;; (add-to-list 'package-pinned-packages '(cider . "melpa-stable") t)
			     ;; (add-hook 'slime-repl-mode-hook
			     ;;           (defun clojure-mode-slime-font-lock ()
			     ;;             (require 'clojure-mode)
			     ;;             (let (font-lock-mode)
			     ;;               (clojure-mode-font-lock-setup))))
			     (add-to-list 'package-pinned-packages '(cider . "melpa-stable") t)

			     ))

(add-hook 'clojure-mode-hook (defun clojure-mode-hook-func ()
			       (interactive)
			       (eldoc-mode t)
			       (emacs-lisp-mode-hook-func)
                               (cider-mode)
			       ))

(add-hook 'html-mode-hook (defun html-mode-hook-func ()
			    (interactive)
			    (emmet-mode t)))

;; (add-hook 'js2-mode-hook 'skewer-mode)
;; (add-hook 'css-mode-hook 'skewer-css-mode)
;; (add-hook 'html-mode-hook 'skewer-html-mode)
;; (add-hook 'lisp-mode-hook (lambda () "for lisp mode" (interactive) (slime)))

;;(require 'ac-cider)
(projectile-global-mode)
(setq projectile-completion-system 'helm)
(setq projectile-indexing-method 'alien)
;;(helm-projectile-on)
(setq projectile-switch-project-action 'helm-projectile-find-file)
(setq projectile-switch-project-action 'helm-projectile)
(add-hook 'cider-mode-hook 'ac-flyspell-workaround)
(add-hook 'cider-mode-hook 'ac-cider-setup)
(add-hook 'cider-repl-mode-hook 'ac-cider-setup)

;;(eval-after-load "auto-complete"
;;  '(progn
;;     (add-to-list 'ac-modes 'cider-mode)
;;     (add-to-list 'ac-modes 'cider-repl-mode)))

(add-hook 'auto-complete-mode-hook 'set-auto-complete-as-completion-at-point-function)
(add-hook 'cider-mode-hook 'set-auto-complete-as-completion-at-point-function)
(global-set-key [f5] 'browse-url)
(global-set-key (kbd "s-r") (defun run-ios ()
                              (set-exec-path-from-shell-PATH)
                              (async-shell-command "react-native" " run-ios --simulator=\"iPhone 4s\"" "run-ios-buffer")))


(let ()
  "Only for react-native environment."
  (ignore-errors
    (add-to-list 'auto-mode-alist '("\\.jsx?$" . web-mode))
    (add-to-list 'auto-mode-alist '("\\.js?$" . js2-mode))
    (add-to-list 'auto-mode-alist '("\\.cshtml?$" . web-mode))
    (setq web-mode-markup-indent-offset 2
          web-mode-css-indent-offset 2
          web-mode-code-indent-offset 2)
    (setq js-indent-level 2)
    (require 'js2-refactor)
    (add-hook 'js2-mode-hook #'js2-refactor-mode)
    (require 'nvm)
    (nvm-use (caar (last (nvm--installed-versions))))

    (add-hook 'projectile-after-switch-project-hook 'mjs/setup-local-eslint)

    (defun mjs/setup-local-eslint ()
      "If ESLint found in node_modules directory - use that for flycheck.
Intended for use in PROJECTILE-AFTER-SWITCH-PROJECT-HOOK."
      (interactive)
      (let ((local-eslint (expand-file-name "./node_modules/.bin/eslint")))
        (setq flycheck-javascript-eslint-executable
              (and (file-exists-p local-eslint) local-eslint))))
    (with-eval-after-load 'flycheck
      (push 'web-mode (flycheck-checker-get 'javascript-eslint 'modes))))
  )

(show-paren-mode 1)
(ido-mode 1)
(ido-everywhere)

(autoload 'gtags-mode "gtags" "" t)
(add-hook 'c-mode-hook 'gtags-mode)
(add-hook 'c++-mode-hook 'gtags-mode)
(add-hook 'java-mode-hook 'gtags-mode)

(provide 'require-cmds-init)
